package kuzmenkov.oip.controller.applet;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.RenderedImage;
import java.net.URL;
import java.util.List;
import java.util.logging.Logger;

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JLabel;

public class ImageUIC extends ParamUIC implements ISelectableUIC, IPolygonSupportedUIC {
	/**
	 * 
	 */
	private static final long serialVersionUID = 7083207178617788775L;

	private Logger log = Logger.getLogger(ImageUIC.class.getName());

	/**
	 * A preferred width of the ui component
	 */
	private int preferWidth;
	/**
	 * A preferred height of the ui component
	 */
	private int preferHeight;
	/**
	 * A list of images. User should select these images
	 */
	private List images;

	private Rectangle2D selection;

	private JComboBox imageBox;

	/**
	 * A panel which renders a selected image
	 */
	private RenderedImagePanel imagePanel;

	private URL codebase;
	private String selectedImage;

	public ImageUIC(Param param, URL codebase, List images, int prefWidth,
			int prefHeight) {
		super(param);
		I18nTool itool = I18nTool.getInstance();
		if (prefWidth < 0 || prefHeight < 0) {
			throw new IllegalArgumentException(itool.getMessage(
					"ImageUIC.illegalPreferredSize", new Object[] {
							new Integer(prefWidth), new Integer(prefHeight) }));
		}
		if (images == null) {
			throw new IllegalArgumentException(itool
					.getMessage("ImageUIC.illegalListOfImages"));
		}
		if (codebase == null)
			throw new IllegalArgumentException(itool
					.getMessage("ImageUIC.illegalCodebase"));

		this.preferHeight = prefHeight;
		this.preferWidth = prefWidth;
		this.images = images;
		this.codebase = codebase;
		initUI();
	}

	private void initUI() {
		setLayout(new GridBagLayout());

		Param param = getParam();
		String name = param.getName();
		String desc = param.getDescription();
		// String defVal = param.getDefaultValue();
		boolean isResult = param.isResult();

		JLabel label21 = new JLabel(name);
		label21.setToolTipText(truncateString(desc,MAX_TIP_LENGTH));
		

		imagePanel = new RenderedImagePanel(name);
		imagePanel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
		imagePanel.setPreferredSize(new Dimension(preferWidth, preferHeight));

		imageBox = new JComboBox(images.toArray());
		imageBox.setPreferredSize(new Dimension(145, 25));
		imageBox.addActionListener(new ImageSelectingL());
		imageBox.setToolTipText(truncateString(desc,MAX_TIP_LENGTH));
		imageBox.setEditable(false);
		imageBox.setSelectedItem(null);

		
		//label21.setVisible(!isResult);
		imageBox.setVisible(!isResult);

		GridBagConstraints c1 = createConstr(0, 0, 2, 1);
		c1.fill = GridBagConstraints.BOTH;
		c1.anchor = GridBagConstraints.CENTER;
		c1.weightx = 100;
		c1.weighty = 100;

		GridBagConstraints c21 = createConstr(0, 1, 1, 1);
		c21.anchor = GridBagConstraints.WEST;

		GridBagConstraints c22 = createConstr(1, 1, 1, 1);
		c22.weightx = 100;
		c22.anchor = GridBagConstraints.WEST;

		add(imagePanel, c1);
		add(label21, c21);
		add(imageBox, c22);
	}

	/**
	 * A listener listens events of an image selection
	 * 
	 * @author Michael Kuzmenkov
	 * 
	 */
	private class ImageSelectingL implements ActionListener {
		// private ImagePanel imagePanel;
		// private Applet applet;

		public ImageSelectingL() {
			// this.imagePanel = imagePanel;
			// this.applet = applet;
		}

		public void actionPerformed(ActionEvent e) {
			log.info("entry");
			JComboBox box = (JComboBox) e.getSource();
			ImageData imageData = (ImageData) box.getSelectedItem();
			if (imageData != null) {
				try {
					selectedImage = imageData.getFilePath();
					RenderedImage image = loadImage(selectedImage);
					
					setValue(image);
				} catch (Exception e1) {
					log.severe(e1.toString());
					e1.printStackTrace();
					selectedImage = null;
				}
			}

		}

	}

	private RenderedOp loadImage(String filePath) throws Exception {
		I18nTool itool = I18nTool.getInstance();
		if (filePath == null || filePath.isEmpty()) {
			log.severe("File path to the selected image is null");
			throw new IllegalArgumentException(itool
					.getMessage("ImageUIC.filePathIsNull"));
		}
		if (!filePath.startsWith("/"))
			filePath = "/" + filePath;

		URL cb = codebase;

		URL imageURL = new URL(cb.getProtocol(), cb.getHost(), cb.getPort(), "/"
				+ ClientService.ROOT_PATH + filePath);

		// Read the image from the designated URL.
		RenderedOp img = JAI.create("url", imageURL);

		// Image img = applet.getImage(imageURL);

		if (img == null) {
			log.warning("Not found the image: " + imageURL);
			imageURL = null;
			throw new Exception(itool
					.getMessage("ImageUIC.unsuccessfulImageLoading"));
		} else
			log.info("The image " + imageURL + " has just started to download");

		return img;
	}

	private GridBagConstraints createConstr(int gridx, int gridy,
			int gridwidth, int gridheight) {
		GridBagConstraints constr = new GridBagConstraints();
		constr.gridx = gridx;
		constr.gridy = gridy;
		constr.gridwidth = gridwidth;
		constr.gridheight = gridheight;
		constr.fill = GridBagConstraints.NONE;
		constr.insets = new Insets(2, 2, 2, 2);

		return constr;
	}

	/*
	 * private String[] getImagePath(List images) { String[] paths = new
	 * String[images.size()]; for (int i = 0; i < paths.length; i++) { ImageData
	 * image = (ImageData) images.get(i); paths[i] = image.getFilePath(); }
	 * return paths; }
	 */
	// public Object getValue() {
	// ImageData imageData = (ImageData) imageBox.getSelectedItem();
	// if (imageData!=null)
	// return imageData.getFilePath();
	// return null;
	// }
	public Object getValue() {
		return selectedImage;
	}

	public void setValue(Object value) {
		log.info("value="+value);
		RenderedImage image = null;
		I18nTool itool = I18nTool.getInstance();
		try {
			if (value instanceof RenderedImage) {
				image = (RenderedImage) value;

			} else if (value instanceof String) {
				String path = (String) value;
				image = loadImage(path);
			} else 
				throw new Exception();
		} catch (Exception e) {
			log.severe(itool.getMessage("ImageUIC.valueIsNotLegal",
					new Object[] { value }));
			e.printStackTrace();
		}
		imagePanel.setImage(image);

	}

	public void setSelection(Rectangle2D selection) {
		this.selection = selection;
		log.info("selection: " + selection);
	}

	public Rectangle2D getSelection() {
		return selection;
	}

	public void setSelectable(boolean isSelectable) {
		imagePanel.setSelectionListener(isSelectable ? this : null);
	}

	public List getPolygons() {
		// TODO a support to input polygons 
		return null;
	}

	public void setPolygons(List polygons) {
		imagePanel.setPolygons(polygons);
	}

	public void setSupport(boolean enable) {
		// always enabled
		
	}

}
